/*
 * Copyright(c) 2015 Reconova Information Technologies Co., Ltd. All rights reserved.
 *
 * 把宏定义和数据结构单独分拆一个文件。这个对使用上没有影响，主要是这样做
 * 内部实现更方便一些。
 *
 *
 * Created by Cyberman Wu on Jul 17th, 2015.
 *
 *
 *
 * 增加YUV420和YUYV（自动转NV12）的支持。
 *
 * Modified by Cyberman Wu on Nov 28th, 2015.
 *
 *
 *
 * 增加YUYV转NV1的支持。
 *
 * Modified by Cybeman Wu on Dec 2nd, 2015.
 */

#ifndef __CAP_TYPES_H__
#define __CAP_TYPES_H__

#include <stdint.h>


/*
 * 硬编码库和V4L2对于Pixel Format定义不一致，所以这两者我们都不采用，而是
 * 另外定义一组名称。
 *
 * 目前H.264硬编码库只能支持这两种格式做为输入。
 */
#define VIDEO_CAP_FMT_NV12              1
#define VIDEO_CAP_FMT_NV21              2
#define VIDEO_CAP_FMT_YUV420            3
/*
 * 这个通常只用于USB摄像头，因为USB摄像头一般只支持YUYV422格式，但我们算法
 * 通常用灰度图，所以我们内部自动转换为NV12来使用。目前库本身不支持多线程，
 * 所以这个转换会带来明显的性能损失（R16上640x480大约在2~3ms）。
 *
 * 注意：
 *   1. 获取灰度图的接口不可用。
 *   2. 获取Zero Copy的帧不进行转换。
 *   3. Zero Copy获取的视频帧不能再编码。
 */
#define VIDEO_CAP_FMT_YUYVtoNV12        4
// Android上用这种格式比较多，但iOS上似乎只支持NV12。
#define VIDEO_CAP_FMT_YUYVtoNV21        5
#define VIDEO_CAP_FMT_MAX               VIDEO_CAP_FMT_YUYVtoNV21


/*
 * 用于获取视频帧的数据结构。
 */
typedef 
struct VCBuf
{
    /*
     * 这两个参数由外部传入，我们不在里面动态分配buffer，这样
     * 更灵活一些。
     */
    uint8_t *buf;
    uint32_t len;
    
    /*
     * 下面是由Video Capture填写的一些输出信息信息。
     */
    // 成功获取到一帧数据之后，实际写入的数据长度要么是帧数据
    // 大小，要么是灰度图大小，取决于用哪个接口。这个值如果放
    // 实际写入的图像数据的话，实际上是多余的。
    // 目前我们放V4L2中返回的数据长度值，因为在有些平台上遇到
    // 过V4L2驱动在后面增加了一些数据，甚至有的还在图像数据前
    // 面增加了数据。我们记录这个值，是在遇到问题时外部应用中
    // 可以判断一下这个值是否异常。
    uint32_t BytesUsed;
    // 毫秒时间戳。
    uint64_t TimeStamp;
} S_VCBuf;




/*
 * 用于Zero Copy接口的数据类型。用前面的类型也可以想办法满足，
 * 或者合并一下；但这样要修改原来的接口。
 * 这个数据结构全部为输出数据，统一由Video Capture接口填写。
 */
typedef 
struct VCZCBuf
{
    /*
     * 指向底层数据获取到的视频数据的起始地址。目前我们的数据
     * 都只支持连续的，具体大小视初始化时配置的分辨率。
     */
    uint8_t *Img;
    // V4L2中返回的数据长度值，因为在有些平台上遇到过V4L2驱动
    // 在后面增加了一些数据，甚至有的还在图像数据前面增加了数
    // 据。我们记录这个值，是在遇到问题时外部应用中可以判断一
    // 下这个值是否异常。
    uint32_t BytesUsed;
    // 毫秒时间戳。
    uint64_t TimeStamp;


    /*
     * 这个用于和底层驱动的buffer应用，目前主要是释放时使用，
     * 不过释放时我们还是传入这个结构，而不是只传入这个值。
     */
    uint32_t index;
} S_VCZCBuf;





#define H264_PROFILE_BASELINE           0
#define H264_PROFILE_MAIN               1
#define H264_PROFILE_HIGH               2


/*
 * 用于获取H.264编码后帧的数据结构。
 */
typedef 
struct H264EncBuf
{
    /*
     * 由外部提供。目前编码器没有信息输出最大可能多大，所以尽量提供大一些，
     * 如果足够一个原始帧，应该是没有问题了。
     */
    uint8_t *buf;
    uint32_t len;

    /*
     * 下面是由Video Capture填写的一些信息。
     */
    // 编码后视频帧数据长度。
    uint32_t BytesUsed;
    // 是否是关键帧（I帧）。
    int IsKeyFrame;
    // 目前对于关键帧我们都在前面附加上SPS和PPS的信息。硬编码库实际上只在
    // 第一帧时生成这个信息，对于保存文件这样做足够了；但对于网络传视频流，
    // 如果第一帧丢掉了，对端收到后面的数据也没办法再解码。
    // 目前我们在所有关键帧前面自动加上SPS&PPS信息，但同时用KeyInfoLen传出
    // 这部分数据的长度。对于大部分应用，这个值可以忽略；而如果有些场景要
    // 把SPS&PPS分拆出来，利用这个长度就可以了。
    uint32_t KeyInfoLen;
} S_H264EncBuf;



#endif  /* __CAP_TYPES_H__ */

